package com.jsftoolkit.base.renderer;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;

/**
 * Interface for stateless render callbacks.
 * <p>
 * Each call allows the callback a chance to render. Each method may be treated
 * the same as the corresponding {@link Renderer} method. (see
 * {@link HtmlRenderer} for minor differences in
 * {@link #encodeChildren(FacesContext, UIComponent)}).
 * 
 * @see HtmlRenderer
 * 
 * @author noah
 * 
 */
public interface RenderCallback {

	/**
	 * Same as {@link Renderer#decode(FacesContext, UIComponent)}.
	 * 
	 * @param context
	 * @param component
	 *            the component
	 */
	void decode(FacesContext context, UIComponent component);

	/**
	 * Called when the opening callback tag is encountered.
	 * 
	 * @param context
	 * @param component
	 * @throws IOException
	 */
	void encodeBegin(FacesContext context, UIComponent component)
			throws IOException;

	/**
	 * Called if and only if the {@link HtmlRenderer#CHILDREN} tag is a child of
	 * the callback tag and of no other callback tag. e.g. In the template:
	 * 
	 * <pre>
	 *      &lt;call-foo&gt;
	 *       &lt;call-bar&gt;
	 *         &lt;div&gt;
	 *          &lt;children/&gt;
	 *         &lt;/div&gt;
	 *       &lt;/call-bar&gt;
	 *      &lt;/call-foo&gt;
	 * </pre>
	 * 
	 * {@link #encodeChildren(FacesContext, UIComponent)} will be called on the
	 * callback bar, but not the callback foo.
	 * <p>
	 * The context for this method differs slightly from a standard
	 * {@link Renderer#encodeChildren(FacesContext, UIComponent)} invocation.
	 * See {@link HtmlRenderer} for details.
	 * 
	 * @param context
	 * @param component
	 * @throws IOException
	 */
	void encodeChildren(FacesContext context, UIComponent component)
			throws IOException;

	/**
	 * Called when the close of the callback tag is encountered.
	 * 
	 * @param context
	 * @param component
	 * @throws IOException
	 */
	void encodeEnd(FacesContext context, UIComponent component)
			throws IOException;
}
